 package server;



import client.Battler;
import client.MapleCharacter;
import client.status.MonsterStatus;
import client.status.MonsterStatusEffect;
import constants.BattleConstants;
import constants.BattleConstants.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import scripting.event.EventScriptManager;
import server.life.*;
import server.maps.MapleMap;
import server.movement.AbsoluteLifeMovement;
import server.movement.LifeMovementFragment;
import server.movement.RelativeLifeMovement;
import server.quest.MapleQuest;
import tools.DateUtil;
import tools.MaplePacketCreator;
import tools.Randomizer;
import tools.StringUtil;
import tools.packet.MobPacket;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;



























 public final class PokemonBattle
 {
/*   32 */   private static final Logger log = LogManager.getLogger(PokemonBattle.class.getName());
/*   33 */   private static final String[] messages = new String[] { "The ball broke free?!", "It appeared to be caught!", "No! It was so close, too!", "Argh! Almost had it!" };
   private static final int WALK_TIME = 2000;
   private static final String wildBGM = "BgmTW/NightField";
   private static final String npcBGM = "BgmTW/YoTaipei";
   private static final String trainerBGM = "BgmCN/PvP";
   private final int mapid;
   private MapleMap map;
/*   40 */   private int[] characterIds = new int[2];
/*   41 */   private Battler[] battlers = new Battler[2];
/*   42 */   private int instanceid = -1;
/*   43 */   private BattleConstants.Turn[] turn = new BattleConstants.Turn[2];
/*   44 */   private String[] attacks = new String[2];
   private boolean disposed = false;
/*   46 */   private Battler[] switches = new Battler[2];
   private List<Integer> npcTeam;

   public PokemonBattle(MapleCharacter init, int monsterId, BattleConstants.PokemonMap mapp) {
/*   50 */     for (Battler b : init.getBattlers()) {
/*   51 */       if (b != null) {
/*   52 */         b.resetStats();
       }
     }
/*   55 */     this.characterIds[0] = init.getId();
/*   56 */     this.characterIds[1] = 0;
/*   57 */     this.instanceid = EventScriptManager.getNewInstanceMapId();
/*   58 */     this.map = init.getClient().getChannelServer().getMapFactory().CreateInstanceMap(init.getMapId(), false, false, false, this.instanceid);
/*   59 */     this.mapid = init.getMapId();
/*   60 */     this.battlers[0] = init.getBattler(0);
/*   61 */     MapleMonsterStats mons = MapleLifeFactory.getMonsterStats(monsterId);
/*   62 */     if (mons == null) {
/*   63 */       dispose(init, true);
/*   64 */       throw new RuntimeException("MONSTER NOT EXIST " + monsterId);
     }
/*   66 */     this.battlers[1] = new Battler(mons);
   }

   public PokemonBattle(MapleCharacter init, List<Integer> monsterId, int npcId, int maxLevel) {
/*   70 */     for (Battler b : init.getBattlers()) {
/*   71 */       if (b != null) {
/*   72 */         b.resetStats();
/*   73 */         if (maxLevel > 0 && b.getLevel() > maxLevel) {
/*   74 */           b.setTempLevel(maxLevel);
/*   75 */           b.resetHP();
         }
       }
     }
/*   79 */     this.characterIds[0] = init.getId();
/*   80 */     this.characterIds[1] = 0;
/*   81 */     this.instanceid = EventScriptManager.getNewInstanceMapId();
/*   82 */     this.map = init.getClient().getChannelServer().getMapFactory().CreateInstanceMap(init.getMapId(), false, false, false, this.instanceid);
/*   83 */     this.mapid = init.getMapId();
/*   84 */     this.battlers[0] = init.getBattler(0);
/*   85 */     this.npcTeam = monsterId;
/*   86 */     MapleMonsterStats mons = MapleLifeFactory.getMonsterStats(((Integer)monsterId.get(0)).intValue());
/*   87 */     if (mons == null) {
/*   88 */       dispose(init, true);
/*   89 */       throw new RuntimeException("MONSTER NOT EXIST " + monsterId.get(0));
     }
/*   91 */     this.battlers[1] = new Battler(mons);
/*   92 */     this.npcTeam.remove(0);
/*   93 */     this.map.spawnNpc(npcId, BattleConstants.getNPCPos(init.getMapId()));
   }


   public PokemonBattle(MapleCharacter init, MapleCharacter init2) {
/*   98 */     this.map = init.getMap();
/*   99 */     this.mapid = init.getMapId();
/*  100 */     if (init2.getMap() != this.map) {
/*  101 */       throw new RuntimeException("INIT MAPS WERE NOT EQUAL: " + init.getMapId() + " vs " + init2.getMapId());
     }
/*  103 */     for (Battler b : init.getBattlers()) {
/*  104 */       if (b != null) {
/*  105 */         b.resetStats();
       }
     }
/*  108 */     for (Battler b : init2.getBattlers()) {
/*  109 */       if (b != null) {
/*  110 */         b.resetStats();
       }
     }
/*  113 */     this.characterIds[0] = init.getId();
/*  114 */     this.characterIds[1] = init2.getId();
/*  115 */     this.battlers[0] = init.getBattler(0);
/*  116 */     this.battlers[1] = init2.getBattler(0);
   }

   public int getInstanceId() {
/*  120 */     return this.instanceid;
   }

   public void giveReward(MapleCharacter chr) {
/*  124 */     if (chr.getMapId() == 925020011) {
/*  125 */       int rr = Randomizer.nextInt(100);
/*  126 */       if (rr < 10) {
/*  127 */         int reward = RandomRewards.getPokemonReward();
/*  128 */         if (MapleInventoryManipulator.checkSpace(chr.getClient(), reward, 1, "")) {
/*  129 */           chr.dropMessage(-6, "You have gained a pokemon item.");
/*  130 */           MapleInventoryManipulator.addById(chr.getClient(), reward, (short)1, "Pokemon prize on NORMAL on " + DateUtil.getCurrentDate());
         } else {
/*  132 */           giveReward(chr);
         }
/*  134 */       } else if (rr < 45) {
/*  135 */         int reward = RandomRewards.getDropReward();
/*  136 */         if (MapleInventoryManipulator.checkSpace(chr.getClient(), reward, 1, "")) {
/*  137 */           MapleInventoryManipulator.addById(chr.getClient(), reward, (short)1, "Pokemon prize on NORMAL on " + DateUtil.getCurrentDate());
         } else {
/*  139 */           giveReward(chr);
         }
/*  141 */       } else if (rr < 70) {
/*  142 */         int reward = RandomRewards.getFishingReward();
/*  143 */         if (MapleInventoryManipulator.checkSpace(chr.getClient(), reward, 1, "")) {
/*  144 */           MapleInventoryManipulator.addById(chr.getClient(), reward, (short)1, "Pokemon prize on NORMAL on " + DateUtil.getCurrentDate());
         } else {
/*  146 */           giveReward(chr);
         }
/*  148 */       } else if (rr < 80) {
/*  149 */         int reward = RandomRewards.getSilverBoxReward();
/*  150 */         if (MapleInventoryManipulator.checkSpace(chr.getClient(), reward, 1, "")) {
/*  151 */           MapleInventoryManipulator.addById(chr.getClient(), reward, (short)1, "Pokemon prize on NORMAL on " + DateUtil.getCurrentDate());
         } else {
/*  153 */           giveReward(chr);
         }
/*  155 */       } else if (rr < 85) {
/*  156 */         int reward = RandomRewards.getGoldBoxReward();
/*  157 */         if (MapleInventoryManipulator.checkSpace(chr.getClient(), reward, 1, "")) {
/*  158 */           MapleInventoryManipulator.addById(chr.getClient(), reward, (short)1, "Pokemon prize on NORMAL on " + DateUtil.getCurrentDate());
         } else {
/*  160 */           giveReward(chr);
         }
/*  162 */       } else if (rr < 90) {
/*  163 */         int reward = RandomRewards.getPeanutReward();
/*  164 */         if (MapleInventoryManipulator.checkSpace(chr.getClient(), reward, 1, "")) {
/*  165 */           MapleInventoryManipulator.addById(chr.getClient(), reward, (short)1, "Pokemon prize on NORMAL on " + DateUtil.getCurrentDate());
         } else {
/*  167 */           giveReward(chr);
         }
       } else {
/*  170 */         chr.dropMessage(-6, "The trainer ran away, ashamed at their defeat, unable to give a reward.");
       }
/*  172 */     } else if (chr.getMapId() == 925020012) {
/*  173 */       int rr = Randomizer.nextInt(100);
/*  174 */       if (rr < 20) {
/*  175 */         int reward = RandomRewards.getPokemonReward();
/*  176 */         if (MapleInventoryManipulator.checkSpace(chr.getClient(), reward, 1, "")) {
/*  177 */           chr.dropMessage(-6, "You have gained a pokemon item.");
/*  178 */           MapleInventoryManipulator.addById(chr.getClient(), reward, (short)1, "Pokemon prize on HARD on " + DateUtil.getCurrentDate());
         } else {
/*  180 */           giveReward(chr);
         }
/*  182 */       } else if (rr < 40) {
/*  183 */         int reward = RandomRewards.getDropReward();
/*  184 */         if (MapleInventoryManipulator.checkSpace(chr.getClient(), reward, 1, "")) {
/*  185 */           MapleInventoryManipulator.addById(chr.getClient(), reward, (short)1, "Pokemon prize on HARD on " + DateUtil.getCurrentDate());
         } else {
/*  187 */           giveReward(chr);
         }
/*  189 */       } else if (rr < 60) {
/*  190 */         int reward = RandomRewards.getFishingReward();
/*  191 */         if (MapleInventoryManipulator.checkSpace(chr.getClient(), reward, 1, "")) {
/*  192 */           MapleInventoryManipulator.addById(chr.getClient(), reward, (short)1, "Pokemon prize on HARD on " + DateUtil.getCurrentDate());
         } else {
/*  194 */           giveReward(chr);
         }
/*  196 */       } else if (rr < 75) {
/*  197 */         int reward = RandomRewards.getSilverBoxReward();
/*  198 */         if (MapleInventoryManipulator.checkSpace(chr.getClient(), reward, 1, "")) {
/*  199 */           MapleInventoryManipulator.addById(chr.getClient(), reward, (short)1, "Pokemon prize on HARD on " + DateUtil.getCurrentDate());
         } else {
/*  201 */           giveReward(chr);
         }
/*  203 */       } else if (rr < 85) {
/*  204 */         int reward = RandomRewards.getGoldBoxReward();
/*  205 */         if (MapleInventoryManipulator.checkSpace(chr.getClient(), reward, 1, "")) {
/*  206 */           MapleInventoryManipulator.addById(chr.getClient(), reward, (short)1, "Pokemon prize on HARD on " + DateUtil.getCurrentDate());
         } else {
/*  208 */           giveReward(chr);
         }
/*  210 */       } else if (rr < 95) {
/*  211 */         int reward = RandomRewards.getPeanutReward();
/*  212 */         if (MapleInventoryManipulator.checkSpace(chr.getClient(), reward, 1, "")) {
/*  213 */           MapleInventoryManipulator.addById(chr.getClient(), reward, (short)1, "Pokemon prize on HARD on " + DateUtil.getCurrentDate());
         } else {
/*  215 */           giveReward(chr);
         }
       } else {
/*  218 */         chr.dropMessage(-6, "The trainer ran away, ashamed at their defeat, unable to give a reward.");
       }
/*  220 */     } else if (chr.getMapId() == 925020013) {
/*  221 */       int rr = Randomizer.nextInt(100);
/*  222 */       if (rr < 40) {
/*  223 */         int reward = RandomRewards.getPokemonReward();
/*  224 */         if (MapleInventoryManipulator.checkSpace(chr.getClient(), reward, 1, "")) {
/*  225 */           chr.dropMessage(-6, "You have gained an evolution item.");
/*  226 */           MapleInventoryManipulator.addById(chr.getClient(), reward, (short)1, "Pokemon prize on HELL on " + DateUtil.getCurrentDate());
         } else {
/*  228 */           giveReward(chr);
         }
/*  230 */       } else if (rr < 50) {
/*  231 */         int reward = RandomRewards.getDropReward();
/*  232 */         if (MapleInventoryManipulator.checkSpace(chr.getClient(), reward, 1, "")) {
/*  233 */           MapleInventoryManipulator.addById(chr.getClient(), reward, (short)1, "Pokemon prize on HELL on " + DateUtil.getCurrentDate());
         } else {
/*  235 */           giveReward(chr);
         }
/*  237 */       } else if (rr < 70) {
/*  238 */         int reward = RandomRewards.getSilverBoxReward();
/*  239 */         if (MapleInventoryManipulator.checkSpace(chr.getClient(), reward, 1, "")) {
/*  240 */           MapleInventoryManipulator.addById(chr.getClient(), reward, (short)1, "Pokemon prize on HELL on " + DateUtil.getCurrentDate());
         } else {
/*  242 */           giveReward(chr);
         }
/*  244 */       } else if (rr < 85) {
/*  245 */         int reward = RandomRewards.getGoldBoxReward();
/*  246 */         if (MapleInventoryManipulator.checkSpace(chr.getClient(), reward, 1, "")) {
/*  247 */           MapleInventoryManipulator.addById(chr.getClient(), reward, (short)1, "Pokemon prize on HELL on " + DateUtil.getCurrentDate());
         } else {
/*  249 */           giveReward(chr);
         }
       } else {
/*  252 */         int reward = RandomRewards.getPeanutReward();
/*  253 */         if (MapleInventoryManipulator.checkSpace(chr.getClient(), reward, 1, "")) {
/*  254 */           MapleInventoryManipulator.addById(chr.getClient(), reward, (short)1, "Pokemon prize on HELL on " + DateUtil.getCurrentDate());
         } else {
/*  256 */           giveReward(chr);
         }
       }
     }
   }

   public void dispose() {
/*  263 */     if (this.map != null) {
/*  264 */       for (Battler battler : this.battlers) {
/*  265 */         if (battler != null && battler.getMonster() != null) {
/*  266 */           this.map.killMonster(battler.getMonster());
/*  267 */           battler.resetStats();
         }
       }
     }
/*  271 */     this.map = null;
/*  272 */     this.battlers = new Battler[2];
/*  273 */     this.turn = new BattleConstants.Turn[2];
/*  274 */     this.attacks = new String[2];
/*  275 */     this.switches = new Battler[2];
/*  276 */     this.characterIds = new int[2];
/*  277 */     this.disposed = true;
/*  278 */     if (this.npcTeam != null) {
/*  279 */       this.npcTeam.clear();
/*  280 */       this.npcTeam = null;
     }
   }

   public void dispose(MapleCharacter chr, boolean dc) {
/*  285 */     boolean npc = (this.npcTeam != null);
/*  286 */     dispose();
/*  287 */     chr.setBattle(null);
/*  288 */     for (Battler b : chr.getBattlers()) {
/*  289 */       if (b != null) {
/*  290 */         b.resetStats();
       }
     }
/*  293 */     if (this.instanceid >= 0) {
/*  294 */       if ((!dc || npc) && chr.getMapId() == this.mapid) {
/*  295 */         MapleMap mapz = chr.getClient().getChannelServer().getMapFactory().getMap(this.mapid);
/*  296 */         chr.changeMap(mapz, mapz.findClosestPortal(chr.getTruePosition()));
       }
/*  298 */       chr.getClient().getChannelServer().getMapFactory().removeInstanceMap(this.instanceid);
/*  299 */     } else if (chr.getMapId() == this.mapid && !dc) {
/*  300 */       chr.fakeRelog();
     }
   }

   public MapleMap getMap() {
/*  305 */     return this.map;
   }

   public Battler getBattler(int index) {
/*  309 */     return this.battlers[index];
   }

   public void updateHP(int i) {
/*  313 */     if (this.battlers[i] != null && this.battlers[i].getMonster() != null && this.characterIds[(i == 0) ? 1 : 0] > 0) {
/*  314 */       MapleCharacter chrr = this.map.getCharacterById(this.characterIds[(i == 0) ? 1 : 0]);
/*  315 */       if (chrr != null) {
/*  316 */         chrr.getClient().announce(MobPacket.showBossHP(9300184, this.battlers[i].getCurrentHP(), this.battlers[i].calcHP()));
       }
     }
   }

   public MapleMonster spawnMonster(Point pos, boolean facingLeft, boolean animation, Battler b) {
/*  322 */     MapleMonster mons = MapleLifeFactory.getMonster(b.getMonsterId());
/*  323 */     if (mons == null) {
/*  324 */       return mons;
     }
/*  326 */     mons.setFake(true);
/*  327 */     mons.setLinkCID((b.getCharacterId() <= 0) ? 1 : b.getCharacterId());
/*  328 */     if (facingLeft) {
/*  329 */       mons.setStance(4);
     }
/*  331 */     this.map.spawnMonster_Pokemon(mons, pos, animation ? 15 : -2);
/*  332 */     b.setMonster(mons);
/*  333 */     for (int i = 0; i < this.characterIds.length; i++) {
/*  334 */       if (this.characterIds[i] == b.getCharacterId()) {
/*  335 */         updateHP(i);
         break;
       }
     }
/*  339 */     return mons;
   }

   public void initiate(MapleCharacter initiator, BattleConstants.PokemonMap mapp) {
/*  343 */     spawnMonster(mapp.pos1, mapp.facingLeft, false, this.battlers[1]);
/*  344 */     initiator.dropMessage(-6, "Wild " + this.battlers[1].getName() + " has appeared! (Level " + this.battlers[1].getLevel() + ")");
/*  345 */     initiator.dropMessage(-3, "Go, " + this.battlers[0].getName() + "! (Level " + this.battlers[0].getLevel() + ")");
/*  346 */     spawnMonster(mapp.pos0, !mapp.facingLeft, true, this.battlers[0]);
/*  347 */     initiator.dropMessage(-6, "What will you do? @use @info @ball @run @battlehelp");
/*  348 */     this.turn[1] = makeRandomTurn();
/*  349 */     initiator.getClient().announce(MaplePacketCreator.musicChange("BgmTW/NightField"));
/*  350 */     initiator.getMonsterBook().monsterSeen(initiator.getClient(), this.battlers[1].getMonsterId(), this.battlers[1].getOriginalName());
/*  351 */     firstTurn(this.battlers[0], this.battlers[1]);
   }

   public void initiate(MapleCharacter initiator, MapleNPC npc) {
/*  355 */     Point ourPos = BattleConstants.getNPCPos(initiator.getMapId());
/*  356 */     spawnMonster(new Point(ourPos.x - 100, ourPos.y), false, true, this.battlers[1]);
/*  357 */     initiator.dropMessage(-6, "Trainer " + npc.getName() + " wants to battle!");
/*  358 */     initiator.dropMessage(-6, "Go, " + this.battlers[1].getName() + "! (Level " + this.battlers[1].getLevel() + ")");
/*  359 */     initiator.dropMessage(-3, "Go, " + this.battlers[0].getName() + "! (Level " + this.battlers[0].getLevel() + ")");
/*  360 */     spawnMonster(new Point(ourPos.x - 400, ourPos.y), true, true, this.battlers[0]);
/*  361 */     initiator.dropMessage(-6, "What will you do? @use @info @ball @run @battlehelp");
/*  362 */     this.turn[1] = makeRandomTurn();
/*  363 */     initiator.getClient().announce(MaplePacketCreator.musicChange("BgmTW/YoTaipei"));
/*  364 */     firstTurn(this.battlers[0], this.battlers[1]);
   }

   public void initiate() {
/*  368 */     MapleCharacter initiator = this.map.getCharacterById(this.battlers[0].getCharacterId());
/*  369 */     MapleCharacter initiator2 = this.map.getCharacterById(this.battlers[1].getCharacterId());
/*  370 */     initiator.dropMessage(-6, initiator2.getName() + " wants to battle!");
/*  371 */     initiator2.dropMessage(-6, initiator.getName() + " wants to battle!");
/*  372 */     this.map.broadcastMessage(MaplePacketCreator.getChatText(initiator.getId(), "Go, " + this.battlers[0].getName() + "! (Level " + this.battlers[0].getLevel() + ")", initiator.getName(), initiator.isGM(), 0));
/*  373 */     this.map.broadcastMessage(MaplePacketCreator.getChatText(initiator2.getId(), "Go, " + this.battlers[1].getName() + "! (Level " + this.battlers[1].getLevel() + ")", initiator2.getName(), initiator2.isGM(), 0));
/*  374 */     spawnMonster(new Point((initiator.getTruePosition()).x + (((initiator.getTruePosition()).x > (initiator2.getTruePosition()).x) ? -100 : 100), (initiator.getTruePosition()).y), ((initiator.getTruePosition()).x < (initiator2.getTruePosition()).x), true, this.battlers[0]);
/*  375 */     spawnMonster(new Point((initiator2.getTruePosition()).x + (((initiator2.getTruePosition()).x > (initiator.getTruePosition()).x) ? -100 : 100), (initiator2.getTruePosition()).y), ((initiator2.getTruePosition()).x < (initiator.getTruePosition()).x), true, this.battlers[1]);
/*  376 */     initiator.dropMessage(-6, "What will you do? @use @info @ball @run @battlehelp");
/*  377 */     initiator2.dropMessage(-6, "What will you do? @use @info @ball @run @battlehelp");
/*  378 */     initiator.getClient().announce(MaplePacketCreator.musicChange("BgmCN/PvP"));
/*  379 */     initiator2.getClient().announce(MaplePacketCreator.musicChange("BgmCN/PvP"));
/*  380 */     firstTurn(this.battlers[0], this.battlers[1]);
/*  381 */     firstTurn(this.battlers[1], this.battlers[0]);
   }

   public void forfeit(MapleCharacter forfeiter, boolean dc) {
/*  385 */     if (!dc && this.turn[(forfeiter.getId() == this.characterIds[0]) ? 0 : 1] != null && this.turn[(forfeiter.getId() == this.characterIds[0]) ? 0 : 1] != BattleConstants.Turn.TRUANT) {
/*  386 */       forfeiter.dropMessage(-6, "You've already selected an action.");
       return;
     }
/*  389 */     if (this.instanceid >= 0) {
/*  390 */       if (!dc && this.battlers[0] != null && this.battlers[1] != null && this.battlers[1].getLevel() > this.battlers[0].getLevel() && this.battlers[1].getLevel() > 1 && Randomizer.nextInt(this.battlers[1].getLevel() - this.battlers[0].getLevel()) / 10 != 0 && this.battlers[0].getAbility() != BattleConstants.PokemonAbility.RunAway) {
/*  391 */         forfeiter.dropMessage(-6, "Couldn't get away!");
/*  392 */         this.turn[1] = makeRandomTurn();
/*  393 */         makeTurn();
         return;
       }
/*  396 */       dispose(forfeiter, dc);
     } else {
/*  398 */       MapleMap theMap = this.map;
/*  399 */       if (theMap == null) {
/*  400 */         theMap = forfeiter.getMap();
/*  401 */         if (theMap == null) {
/*  402 */           dispose(forfeiter, dc);
           return;
         }
       }
/*  406 */       theMap.broadcastMessage(MaplePacketCreator.serverNotice(6, forfeiter.getName() + " has left the match."));
/*  407 */       if (!this.disposed) {
/*  408 */         dispose((forfeiter.getId() == this.characterIds[0]) ? theMap.getCharacterById(this.characterIds[1]) : theMap.getCharacterById(this.characterIds[0]), dc);
       }
/*  410 */       dispose(forfeiter, dc);
     }
   }

   public boolean attack(MapleCharacter chr, String name) {
/*  415 */     if (this.battlers[0] == null || this.battlers[1] == null || (this.turn[(chr.getId() == this.characterIds[0]) ? 0 : 1] != null && (this.turn[(chr.getId() == this.characterIds[0]) ? 0 : 1] != BattleConstants.Turn.TRUANT || this.attacks[(chr.getId() == this.characterIds[0]) ? 0 : 1] != null))) {
/*  416 */       return false;
     }
/*  418 */     this.attacks[(chr.getId() == this.characterIds[0]) ? 0 : 1] = name;
/*  419 */     if (this.turn[(chr.getId() == this.characterIds[0]) ? 0 : 1] == null) {
/*  420 */       this.turn[(chr.getId() == this.characterIds[0]) ? 0 : 1] = BattleConstants.Turn.ATTACK;
     }
/*  422 */     if (this.turn[(chr.getId() == this.characterIds[0]) ? 1 : 0] != null) {
/*  423 */       makeTurn();
     }
/*  425 */     return true;
   }

   public boolean switchBattler(MapleCharacter chr, Battler b) {
     try {
/*  430 */       if (b.getCurrentHP() <= 0L || this.turn[(chr.getId() == this.characterIds[0]) ? 0 : 1] != null) {
/*  431 */         return false;
       }
/*  433 */       if (b == this.battlers[(chr.getId() == this.characterIds[0]) ? 0 : 1] || this.battlers[(chr.getId() == this.characterIds[0]) ? 1 : 0] == null) {
/*  434 */         return false;
       }
/*  436 */       if (this.battlers[(chr.getId() == this.characterIds[0]) ? 1 : 0] != null && this.battlers[(chr.getId() == this.characterIds[0]) ? 1 : 0].getAbility() == BattleConstants.PokemonAbility.ShadowTag) {
/*  437 */         return false;
       }
/*  439 */       this.turn[(chr.getId() == this.characterIds[0]) ? 0 : 1] = BattleConstants.Turn.SWITCH;
/*  440 */       this.switches[(chr.getId() == this.characterIds[0]) ? 0 : 1] = b;
/*  441 */       if (this.turn[(chr.getId() == this.characterIds[0]) ? 1 : 0] != null) {
/*  442 */         makeTurn();
       }
/*  444 */       return true;
/*  445 */     } catch (NullPointerException e) {
/*  446 */       log.error(e);
/*  447 */       return false;
     }
   }

   public boolean useBall(MapleCharacter user, BattleConstants.PokemonItem itemId) {
/*  452 */     if (this.battlers[1] == null || user == null) {
/*  453 */       return false;
     }
/*  455 */     boolean toBox = false;
/*  456 */     int highestLevel = 0;
/*  457 */     for (Battler b : user.getBattlers()) {
/*  458 */       if (b != null && b.getLevel() > highestLevel) {
/*  459 */         highestLevel = b.getLevel();
       }
/*  461 */       if (b != null && b.getMonsterId() == this.battlers[1].getMonsterId()) {
/*  462 */         toBox = true;
       }
     }
/*  465 */     if (this.turn[1] == BattleConstants.Turn.DISABLED || (this.turn[0] != null && this.turn[0] != BattleConstants.Turn.TRUANT) || this.battlers[0] == null || this.battlers[1] == null || highestLevel + 5 < this.battlers[1].getLevel() || this.npcTeam != null || this.disposed) {
/*  466 */       return false;
     }
/*  468 */     if (this.turn[0] == BattleConstants.Turn.TRUANT) {
/*  469 */       this.turn[0] = null;
     }
/*  471 */     user.dropMessage(-3, "Go, " + StringUtil.makeEnumHumanReadable(itemId.name()) + "!");
/*  472 */     catchEffect(this.battlers[1].getMonster());
/*  473 */     String mName = this.battlers[1].getOriginalName();
/*  474 */     long rand = Math.round(this.battlers[1].canCatch(itemId.catchChance));
/*  475 */     for (int i = 0; i < messages.length; i++) {
/*  476 */       if (Randomizer.nextInt(256) <= rand) {
/*  477 */         if (i != messages.length - 1) {
/*  478 */           Timer.EtcTimer.getInstance().schedule(() -> { if (!this.disposed) { user.getClient().announce(MaplePacketCreator.playSound("Cokeplay/Fall")); catchEffect(this.battlers[1].getMonster()); } else { dispose(); }  },(2000 * i + 2000));



         }
         else {



/*  487 */           this.turn[1] = BattleConstants.Turn.DISABLED;
/*  488 */           boolean toBo = (toBox || user.countBattlers() >= 6);
/*  489 */           Timer.EtcTimer.getInstance().schedule(() -> { if (!this.disposed) { this.map.killMonster(this.battlers[1].getMonster()); user.getClient().announce(MaplePacketCreator.playSound("Romio/discovery")); user.dropMessage(-6, "Monster " + this.battlers[1].getName() + " has been successfully caught!"); caughtMonster(user, mName, toBo); } else { dispose(); }  },(2000 * i + 2000));









/*  499 */           return true;
         }
       } else {
/*  502 */         this.turn[1] = BattleConstants.Turn.DISABLED;
/*  503 */         String msgg = messages[i];
/*  504 */         Timer.EtcTimer.getInstance().schedule(() -> { if (!this.disposed) { user.dropMessage(-3, msgg); this.turn[1] = makeRandomTurn(); makeTurn(); } else { dispose(); }  },(2000 * i + 2500));








/*  513 */         return true;
       }
     }
/*  516 */     return true;
   }

   public void catchEffect(MapleMonster mons) {
/*  520 */     this.map.broadcastMessage(MobPacket.killMonster(mons.getObjectId(), 0));
/*  521 */     this.map.broadcastMessage(MobPacket.makeMonsterEffect(mons, 15));
   }

   public BattleConstants.Turn makeRandomTurn() {
/*  525 */     if (this.battlers[1] == null || this.battlers[0] == null)
/*  526 */       return BattleConstants.Turn.DISABLED; 
/*  527 */     if (this.npcTeam == null && this.battlers[1].getLevel() < this.battlers[0].getLevel() && this.battlers[1].getLevel() >= 1 && Randomizer.nextInt(this.battlers[0].getLevel() - this.battlers[1].getLevel()) > 10 && Randomizer.nextInt(50) >= 40) {
/*  528 */       return BattleConstants.Turn.SWITCH;
     }
/*  530 */     return BattleConstants.Turn.ATTACK;
   }

   public void firstTurn(Battler ours, Battler theirs) {
/*  534 */     if (ours.getAbility() == BattleConstants.PokemonAbility.Forewarn) {
/*  535 */       this.map.broadcastMessage(MaplePacketCreator.serverNotice(6, theirs.getName() + "'s type is " + theirs.getElementString() + "!"));
/*  536 */     } else if (ours.getAbility() == BattleConstants.PokemonAbility.Frisk) {
/*  537 */       this.map.broadcastMessage(MaplePacketCreator.serverNotice(6, theirs.getName() + "'s item is " + theirs.getItemString() + "!"));
/*  538 */     } else if (ours.getAbility() == BattleConstants.PokemonAbility.Intimidate) {
/*  539 */       theirs.setMod(BattleConstants.PokemonStat.ATK, theirs.decreaseMod(theirs.getMod(BattleConstants.PokemonStat.ATK)));
/*  540 */       this.map.broadcastMessage(MaplePacketCreator.serverNotice(6, ours.getName() + "'s Intimidate scared the opponent!"));
     }
   }

   public void caughtMonster(MapleCharacter user, String mName, boolean toBox) {
/*  545 */     if (toBox) {
/*  546 */       user.getBoxed().add(this.battlers[1]);
     } else {
/*  548 */       user.getBattlers()[user.countBattlers()] = this.battlers[1];
     }
/*  550 */     this.battlers[1].setCharacterId(user.getId());
/*  551 */     user.changedBattler();
/*  552 */     user.getMonsterBook().monsterCaught(user.getClient(), this.battlers[1].getMonsterId(), mName);
/*  553 */     dispose(user, false);
   }


   public void makeTurn() {
    final int theFirst;
    int[] order;
    if (turn[0] != BattleConstants.Turn.SWITCH && (turn[1] == BattleConstants.Turn.SWITCH || (battlers[1] != null && battlers[0] != null && ((battlers[1].getItem() != null && battlers[1].getItem() == BattleConstants.HoldItem.Orange_Star && Randomizer.nextBoolean()) || battlers[1].getSpeed() > battlers[0].getSpeed()) && !(battlers[0].getItem() != null && battlers[0].getItem() == BattleConstants.HoldItem.Orange_Star && Randomizer.nextBoolean())))) {
        order = new int[]{1, 0};
        theFirst = 1;
    } else {
        order = new int[]{0, 1};
        theFirst = 0;
    }
    int timeFirst = WALK_TIME / 8;
    for (final int i : order) {
        if (turn[i] != null && battlers[i == 1 ? 0 : 1] != null && turn[i] != BattleConstants.Turn.DISABLED) {
            if (npcTeam == null && i == 1 && turn[i] == BattleConstants.Turn.SWITCH && instanceid >= 0) { //wild battle running, special exception
                MapleCharacter chr = map.getCharacterById(characterIds[0]);
                chr.dropMessage(-6, "The wild monster fled.");
                dispose(chr, false);
                return;
            }
            if (battlers[i] != null) {
                battlers[i].addMonsterId(battlers[i == 1 ? 0 : 1].getMonsterId());
            }
            Timer.EtcTimer.getInstance().schedule(() -> {
                if (map == null || turn[i] == null || disposed || battlers[i == 1 ? 0 : 1] == null) {
                    return;
                }
                switch (turn[i]) {
                    case TRUANT:
                        if (battlers[i] != null) {
                            map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + " was loafing around!"));
                        }
                        break;
                    case SWITCH:
                        if (battlers[i == 1 ? 0 : 1].getMonster() == null) {
                            map.broadcastMessage(MaplePacketCreator.serverNotice(5, "The move could not be made due to an error."));
                            return;
                        }
                        boolean left = battlers[i == 1 ? 0 : 1].getMonster().isFacingLeft();
                        Point pos = new Point(battlers[i == 1 ? 0 : 1].getMonster().getTruePosition().x + (left ? -300 : 300), battlers[i == 1 ? 0 : 1].getMonster().getTruePosition().y - 20);
                        if (battlers[i] != null) {
                            if (battlers[i].getMonster() == null) {
                                map.broadcastMessage(MaplePacketCreator.serverNotice(5, "The move could not be made due to an error."));
                                return;
                            }
                            map.broadcastMessage(MaplePacketCreator.getChatText(characterIds[i], "Return, " + battlers[i].getName() + "!","", false, 0));
                            pos = battlers[i].getMonster().getPosition();
                            left = !battlers[i].getMonster().isFacingLeft();
                            map.killMonster(battlers[i].getMonster());
                            battlers[i].wipe();
                            if (battlers[i].getAbility() == BattleConstants.PokemonAbility.NaturalCure) {
                                battlers[i].wipeStatus();
                            } else if (battlers[i].getAbility() == BattleConstants.PokemonAbility.Regenerator) {
                                battlers[i].damage((int) -(battlers[i].calcHP() / 3), null, 0, true);
                            }
                        }
                        battlers[i] = switches[i];
                        if (battlers[i] == null) {
                            map.broadcastMessage(MaplePacketCreator.serverNotice(5, "The move could not be made due to an error."));
                            return;
                        }
                        if (i == 1 && npcTeam != null) {
                            map.broadcastMessage(MaplePacketCreator.serverNotice(5, "Go, " + battlers[i].getName() + "! (Level " + battlers[i].getLevel() + ")"));
                        } else {
                            map.broadcastMessage(MaplePacketCreator.getChatText(characterIds[i], "Go, " + battlers[i].getName() + "! (Level " + battlers[i].getLevel() + ")","", false, 0));
                        }
                        spawnMonster(pos, left, true, battlers[i]);
                        firstTurn(battlers[i], battlers[i == 0 ? 1 : 0]);
                        break;
                    case ATTACK:
                        //AttackPower = (level + rand(level)) here
                        //element
                        if (battlers[i] == null || battlers[i].getMonster() == null) {
                            map.broadcastMessage(MaplePacketCreator.serverNotice(5, "The move could not be made due to an error."));
                            return;
                        }
                        if (attacks[i] != null) {
                            map.broadcastMessage(MaplePacketCreator.getChatText(characterIds[i], battlers[i].getName() + ", use " + attacks[i] + "!","", false, 0));
                        }
                        battlers[i].decreaseStatusTurns();
                        boolean st = false;
                        if (battlers[i].getAbility() == BattleConstants.PokemonAbility.ShedSkin && Randomizer.nextBoolean()) {
                            battlers[i].decreaseStatusTurns();
                        }
                        final MonsterStatus s;
                        if (battlers[i].getCurrentStatus() != null) {
                            if (battlers[i].getAbility() == BattleConstants.PokemonAbility.Guts) {
                                battlers[i].setMod(BattleConstants.PokemonStat.ATK, battlers[i].decreaseMod(battlers[i].getMod(BattleConstants.PokemonStat.ATK)));
                            } else if (battlers[i].getAbility() == BattleConstants.PokemonAbility.MarvelScale) {
                                battlers[i].setMod(BattleConstants.PokemonStat.DEF, battlers[i].decreaseMod(battlers[i].getMod(BattleConstants.PokemonStat.DEF)));
                            } else if (battlers[i].getAbility() == BattleConstants.PokemonAbility.QuickFeet) {
                                battlers[i].setMod(BattleConstants.PokemonStat.SPEED, battlers[i].decreaseMod(battlers[i].getMod(BattleConstants.PokemonStat.SPEED)));
                            }
                            s = battlers[i].getCurrentStatus().getStati();
                            switch (s) {
                                case MOB_STAT_Stun:
                                    map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + " is stunned and cannot move!"));
                                    st = true;
                                    break;
                                case MOB_STAT_Freeze:
                                    map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + " is frozen and cannot move!"));
                                    st = true;
                                    break;
                                case MOB_STAT_Weakness:
                                    battlers[i].setMod(BattleConstants.PokemonStat.SPATK, battlers[i].increaseMod(battlers[i].getMod(BattleConstants.PokemonStat.SPATK)));
                                    if (battlers[i].getAbility() == BattleConstants.PokemonAbility.MagicGuard) {
                                        break;
                                    }
                                    battlers[i].damage((int) battlers[i].calcHP() / 16, map, battlers[i == 0 ? 1 : 0] == null ? 0 : battlers[i == 0 ? 1 : 0].getMonsterId(), true);
                                    updateHP(i);
                                    map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + " was hurt " + (battlers[i].calcHP() / 16) + " damage by imprint!"));
                                    break;
                                case MOB_STAT_Blind:
                                    if (battlers[i].getAbility() == PokemonAbility.EarlyBird) {
                                        battlers[i].decreaseStatusTurns();
                                        break;
                                    }
                                    if (battlers[i == 1 ? 0 : 1].getAbility() != PokemonAbility.BadDreams) {
                                        break;
                                    }
                                    if (battlers[i].getAbility() == PokemonAbility.MagicGuard) {
                                        break;
                                    }
                                    battlers[i].damage((int) battlers[i].calcHP() / 16, map, battlers[i == 0 ? 1 : 0] == null ? 0 : battlers[i == 0 ? 1 : 0].getMonsterId(), true);
                                    updateHP(i);
                                    map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + " was hurt " + (battlers[i].calcHP() / 16) + " damage by the opponent's Bad Dreams!"));
                                    break;
                                case MOB_STAT_Poison:
                                    if (battlers[i].getAbility() == PokemonAbility.MagicGuard) {
                                        break;
                                    }
                                    battlers[i].damage((int) (battlers[i].getAbility() == PokemonAbility.PoisonHeal ? -(battlers[i].calcHP() / 16) : (battlers[i].calcHP() / 16)), map, battlers[i == 0 ? 1 : 0] == null ? 0 : battlers[i == 0 ? 1 : 0].getMonsterId(), true);
                                    updateHP(i);
                                    map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + " was hurt " + (battlers[i].calcHP() / 16) + " damage by poison!"));
                                    break;
                                case MOB_STAT_Web:
                                    if (Randomizer.nextInt(4) == 0) {
                                        map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + " was paralyzed and could not move!"));
                                        st = true;
                                    }
                                    //fallthrough is intended
                                case MOB_STAT_Speed:
                                    battlers[i].setMod(PokemonStat.SPEED, battlers[i].increaseMod(battlers[i].getMod(PokemonStat.SPEED)));
                                    break;
                                case MOB_STAT_Darkness:
                                    map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + " is angry and confused!"));
                                    if (Randomizer.nextBoolean() && battlers[i].getAbility() != PokemonAbility.MagicGuard) {
                                        battlers[i].damage((int) battlers[i].calcHP() / 16, map, battlers[i == 0 ? 1 : 0] == null ? 0 : battlers[i == 0 ? 1 : 0].getMonsterId(), true);
                                        updateHP(i);
                                        map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + " was hurt " + (battlers[i].calcHP() / 16) + " damage in its rage!"));
                                        st = true;
                                    }
                                    battlers[i].setMod(PokemonStat.ATK, battlers[i].decreaseMod(battlers[i].getMod(PokemonStat.ATK)));
                                    battlers[i].setMod(PokemonStat.SPATK, battlers[i].decreaseMod(battlers[i].getMod(PokemonStat.SPATK)));
                                    battlers[i].setMod(PokemonStat.DEF, battlers[i].increaseMod(battlers[i].getMod(PokemonStat.DEF)));
                                    battlers[i].setMod(PokemonStat.SPDEF, battlers[i].increaseMod(battlers[i].getMod(PokemonStat.SPDEF)));
                                    break;
                            }
                        } else {
                            s = null;
                        }
                        if (st) {
                            break;
                        }
                        final boolean extraEffects = battlers[i].getAbility() != PokemonAbility.SheerForce && battlers[i == 1 ? 0 : 1].getAbility() != PokemonAbility.ShieldDust && s != MonsterStatus.MOB_STAT_MagicCrash;
                        int critChance = 20;
                        if (battlers[i == 0 ? 1 : 0].getAbility() != PokemonAbility.Klutz && battlers[i].getItem() == HoldItem.Green_Star) {
                            critChance /= 2;
                        }
                        if (battlers[i].getAbility() == PokemonAbility.SuperLuck || battlers[i].getAbility() == PokemonAbility.SereneGrace) {
                            critChance /= 2;
                        }
                        final Point startPos = battlers[i].getMonster().getPosition();
                        Point maskedPos = null;
                        final int origStance = battlers[i].getMonster().getStance();
                        final int atk = Randomizer.nextInt(battlers[i].getMonster().getStats().getMobAttacks().size() + 1);
                        final MobAttackInfo theAtk = (atk > 0 ? battlers[i].getMonster().getStats().getMobAttack(atk - 1) : null);
                        final boolean speshul = theAtk != null && (theAtk.magic || theAtk.MADamage > theAtk.PADamage);
                        final PokemonElement element = (speshul || Randomizer.nextInt(5) == 0) && s != MonsterStatus.MOB_STAT_Seal && battlers[i == 0 ? 1 : 0].getAbility() != PokemonAbility.Normalize && battlers[i].getElementSize() > 0 ? battlers[i].getElements()[(battlers[i].getElementSize() == 1 ? 0 : Randomizer.nextInt(battlers[i].getElementSize()))] : PokemonElement.None;
                        final boolean stab = element != PokemonElement.None,
                                critical = Randomizer.nextInt(critChance) == 0 && extraEffects,
                                flinch = Randomizer.nextInt(battlers[i].getAbility() == PokemonAbility.SereneGrace ? 25 : 50) == 0 && extraEffects;
                        PokemonStat decc = null,
                                incc = null;
                        MonsterStatus statt = null;
                        final int levelDec = Randomizer.nextInt(10) == 0 ? 2 : 1,
                                levelInc = Randomizer.nextInt(10) == 0 ? 2 : 1;
                        long base = battlers[i].getLevel() + 1; //dmg reduction like actual ms, but not dmg increase

                        int incDivisor = 1;
                        if (battlers[i == 0 ? 1 : 0].getAbility() != PokemonAbility.Klutz && battlers[i].getItem() == HoldItem.Herb_Pouch) {
                            incDivisor *= 2;
                        }
                        if (battlers[i].getAbility() == PokemonAbility.SereneGrace) {
                            incDivisor *= 2;
                        }
                        if (extraEffects && battlers[i == 1 ? 0 : 1].getAbility() != PokemonAbility.ClearBody && battlers[i == 1 ? 0 : 1].getAbility() != PokemonAbility.BigPecks && Randomizer.nextInt(20 / incDivisor) == 0) { //inflict stat change, decrease base
                            base = (base * 9) / 10;
                            decc = (stab || speshul ? PokemonStat.SPDEF : PokemonStat.DEF);
                        } else if (extraEffects && battlers[i == 1 ? 0 : 1].getAbility() != PokemonAbility.HyperCutter && battlers[i == 1 ? 0 : 1].getAbility() != PokemonAbility.ClearBody && Randomizer.nextInt(20 / incDivisor) == 0) { //inflict stat change, decrease base
                            base = (base * 9) / 10;
                            decc = (stab || speshul ? PokemonStat.SPATK : PokemonStat.ATK);
                        } else if (extraEffects && battlers[i == 1 ? 0 : 1].getAbility() != PokemonAbility.ClearBody && Randomizer.nextInt(50 / incDivisor) == 0) { //inflict stat change, decrease base
                            base = (base * 9) / 10;
                            decc = (stab || speshul ? PokemonStat.EVA : PokemonStat.SPEED);
                        }
                        int decDivisor = 1;
                        if (battlers[i == 0 ? 1 : 0].getAbility() != PokemonAbility.Klutz && battlers[i].getItem() == HoldItem.Ripped_Note) {
                            decDivisor *= 2;
                        }
                        if (battlers[i].getAbility() == PokemonAbility.SereneGrace) {
                            decDivisor *= 2;
                        }
                        if (extraEffects && Randomizer.nextInt(20 / decDivisor) == 0) { //inflict stat change, decrease base
                            base = (base * 9) / 10;
                            incc = (stab || speshul ? PokemonStat.SPDEF : PokemonStat.DEF);
                        } else if (extraEffects && Randomizer.nextInt(20 / decDivisor) == 0) { //inflict stat change, decrease base
                            base = (base * 9) / 10;
                            incc = (stab || speshul ? PokemonStat.SPATK : PokemonStat.ATK);
                        } else if (extraEffects && Randomizer.nextInt(50 / decDivisor) == 0) { //inflict stat change, decrease base
                            base = (base * 9) / 10;
                            incc = (stab || speshul ? PokemonStat.ACC : PokemonStat.SPEED);
                        }
                        double eez = element.getEffectiveness(battlers[i == 1 ? 0 : 1].getElements());
                        final double ee = (eez <= 0.0 && battlers[i].getAbility() == PokemonAbility.Scrappy ? 1.0 : eez);
                        int statDivisor = 1;
                        if (battlers[i == 0 ? 1 : 0].getAbility() != PokemonAbility.Klutz && battlers[i].getItem() == HoldItem.King_Star) {
                            statDivisor *= 2;
                        }
                        if (battlers[i].getAbility() == PokemonAbility.SereneGrace) {
                            statDivisor *= 2;
                        }
                        if (extraEffects && Randomizer.nextInt(33 / statDivisor) == 0 && ee >= 1.0) {
                            switch (element) {
                                case None:
                                case Normal:
                                case Immortal:
                                    statt = MonsterStatus.MOB_STAT_Stun;
                                    break;
                                case Enchanted:
                                    statt = MonsterStatus.MOB_STAT_Weakness;
                                    break;
                                case Reptile:
                                case Mammal:
                                    statt = MonsterStatus.MOB_STAT_Seal;
                                    break;
                                case Ice:
                                    statt = MonsterStatus.MOB_STAT_Freeze;
                                    break;
                                case Lightning:
                                    statt = MonsterStatus.MOB_STAT_Web;
                                    break;
                                case Fish:
                                    statt = MonsterStatus.MOB_STAT_Speed;
                                    break;
                                case Plant:
                                case Poison:
                                    statt = MonsterStatus.MOB_STAT_Poison;
                                    break;
                                case Spirit:
                                    statt = MonsterStatus.MOB_STAT_Showdown;
                                    break;
                                case Holy:
                                    statt = MonsterStatus.MOB_STAT_MagicCrash;
                                    break;
                                case Dark:
                                    statt = MonsterStatus.MOB_STAT_Blind;
                                    break;
                            }
                        }
                        if (extraEffects && statt == null && theAtk != null && theAtk.getDiseaseSkill() > 0 && Randomizer.nextInt(10 / statDivisor) == 0) {
                            statt = MonsterStatus.getBySkill_Pokemon(theAtk.getDiseaseSkill());
                        }
                        if (statt == null && battlers[i].getAbility() == PokemonAbility.PoisonTouch && Randomizer.nextInt(5) == 0) {
                            statt = MonsterStatus.MOB_STAT_Poison;
                        }
                        final PokemonStat dec = decc;
                        final PokemonStat inc = incc;
                        final MonsterStatus stat = statt;
                        final long basedamagee;
                        if (ee > 0.0) {
                            double stabModifier = battlers[i == 0 ? 1 : 0].getAbility() != PokemonAbility.Klutz && battlers[i].getItem() == HoldItem.Medal ? 0.3 : 0.0;
                            if (battlers[i].getAbility() == PokemonAbility.Adaptability) {
                                stabModifier += 0.3;
                            } else if (battlers[i].getAbility() == PokemonAbility.Blaze && battlers[i].getHPPercent() <= 33 && element == PokemonElement.Fire) {
                                stabModifier += 0.5;
                            } else if (battlers[i].getAbility() == PokemonAbility.Torrent && battlers[i].getHPPercent() <= 33 && element == PokemonElement.Fish) {
                                stabModifier += 0.5;
                            } else if (battlers[i].getAbility() == PokemonAbility.Overgrow && battlers[i].getHPPercent() <= 33 && element == PokemonElement.Plant) {
                                stabModifier += 0.5;
                            }
                            if (battlers[i == 0 ? 1 : 0].getAbility() == PokemonAbility.Filter) {
                                stabModifier -= 0.5;
                            }
                            basedamagee = (long) Math.max(1, Math.ceil(((battlers[i].getAbility() == PokemonAbility.Analytic && theFirst != i ? 1.0 : 0.75) + (battlers[i].getLevel() / 200.0)) * (!element.special ? battlers[i].getATK(atk) : battlers[i].getSpATK(atk)) * (base / 5.0) * (100.0 - (!element.special ? battlers[i == 1 ? 0 : 1].getDEF() : battlers[i == 1 ? 0 : 1].getSpDEF())) / 100.0 + 2) * (stab ? (stabModifier + 3.0) : 2.0) * Math.round(ee * 2.0 * (battlers[i == 0 ? 1 : 0].getAbility() != PokemonAbility.Klutz && battlers[i].getItem() == HoldItem.Other_World_Key && ee >= 2.0 ? 1.1 : 1.0)) * (35.0 + Randomizer.nextInt(15)) / 200.0);
                        } else {
                            basedamagee = 1;
                        }
                        final byte skillByte = (byte) (atk <= 0 ? -1 : (26 + (atk - 1) * 2 + battlers[i].getMonster().getFacingDirection()));
                        final List<LifeMovementFragment> moves = new ArrayList<>();
                        if (theAtk == null) { //simple walk to monster -> atk -> walk back
                            AbsoluteLifeMovement alm = new AbsoluteLifeMovement(0, battlers[i == 0 ? 1 : 0].getMonster().getPosition(), WALK_TIME, battlers[i].getMonster().getFacingDirection() + 2);
                            alm.defaulted();
                            moves.add(alm);
                            alm = new AbsoluteLifeMovement(0, startPos, WALK_TIME, (battlers[i].getMonster().getFacingDirection() == 1 ? 0 : 1) + 2);
                            alm.defaulted();
                            moves.add(alm);
                            alm = new AbsoluteLifeMovement(0, startPos, 0, origStance);
                            alm.defaulted();
                            moves.add(alm);
                        } else { //walk to required distance -> atk -> walk back if any
                            AbsoluteLifeMovement alm;
                            //if range is enough, then don't move at all :P
                            final boolean shouldAdd = (startPos.x < battlers[i == 0 ? 1 : 0].getMonster().getTruePosition().x && battlers[i == 0 ? 1 : 0].getMonster().getTruePosition().x - theAtk.getRange() > startPos.x) || (startPos.x > battlers[i == 0 ? 1 : 0].getMonster().getTruePosition().x && battlers[i == 0 ? 1 : 0].getMonster().getTruePosition().x + theAtk.getRange() < startPos.x);
                            if (shouldAdd) { //walk up to the required range of the attack
                                List<LifeMovementFragment> moves2 = new ArrayList<>();
                                maskedPos = new Point(battlers[i == 0 ? 1 : 0].getMonster().getTruePosition().x + (startPos.x < battlers[i == 0 ? 1 : 0].getMonster().getTruePosition().x ? -theAtk.getRange() : theAtk.getRange()), battlers[i == 0 ? 1 : 0].getMonster().getTruePosition().y);
                                alm = new AbsoluteLifeMovement(0, maskedPos, WALK_TIME, battlers[i].getMonster().getFacingDirection() + 2);
                                alm.defaulted();
                                moves2.add(alm); //separate for this movement only, as we must move THEN attack
                                //map.broadcastMessage(MobPacket.moveMonster(false, (byte) -1, 0, 0, 0, battlers[i].getMonster().getObjectId(), startPos, moves2));
                            }
                            RelativeLifeMovement rlm = new RelativeLifeMovement(2, maskedPos == null ? battlers[i == 0 ? 1 : 0].getMonster().getPosition() : new Point(0, 0), 0, battlers[i].getMonster().getFacingDirection() + 2);
                            moves.add(rlm);
                            if (shouldAdd) {
                                alm = new AbsoluteLifeMovement(0, maskedPos, Math.min(theAtk.attackAfter, WALK_TIME - WALK_TIME / 2), battlers[i].getMonster().getFacingDirection() + 2);
                                alm.defaulted(); //stay at the point located for a certain time
                                moves.add(alm);
                                alm = new AbsoluteLifeMovement(0, startPos, WALK_TIME - Math.min(theAtk.attackAfter, WALK_TIME - WALK_TIME / 2), (battlers[i].getMonster().getFacingDirection() == 1 ? 0 : 1) + 2);
                                alm.defaulted(); //then come back quickly
                                moves.add(alm);
                            }
                            alm = new AbsoluteLifeMovement(0, startPos, 0, origStance);
                            alm.defaulted();
                            moves.add(alm);
                        }
                        final Point mPos = maskedPos;
                        if (mPos == null) {
                            //map.broadcastMessage(MobPacket.moveMonster(skillByte > 0, skillByte, 0, 0, 0, battlers[i].getMonster().getObjectId(), startPos, moves));
                            moves.clear();
                        }
                        Timer.EtcTimer.getInstance().schedule(() -> {
                            if (disposed || map == null || battlers[i == 1 ? 0 : 1] == null || battlers[i] == null) {
                                return;
                            }
                            if (mPos != null) {
                                // map.broadcastMessage(MobPacket.moveMonster(skillByte > 0, skillByte, 0, 0, 0, battlers[i].getMonster().getObjectId(), mPos, moves));
                                moves.clear();
                            }
                            long basedamage = basedamagee;
                            if (battlers[i == 0 ? 1 : 0].getAbility() != PokemonAbility.NoGuard && battlers[i].getAbility() != PokemonAbility.NoGuard && battlers[i].getACC() < (Randomizer.nextInt(1 + battlers[i == 1 ? 0 : 1].getEVA()) * (s == MonsterStatus.MOB_STAT_Blind ? 2 : 1))) {
                                map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + "'s attack missed!"));
                                basedamage = 0;
                            } else {
                                if (ee <= 0.0) {
                                    map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + "'s attack didn't affect " + battlers[i == 0 ? 1 : 0].getName() + "..."));
                                } else if (ee < 1.0) {
                                    if (battlers[i == 0 ? 1 : 0].getAbility() == PokemonAbility.WonderGuard) {
                                        basedamage = 0;
                                        map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + "'s attack was negated by Wonder Guard!"));
                                    } else if (battlers[i == 0 ? 1 : 0].getAbility() != PokemonAbility.Klutz && battlers[i == 0 ? 1 : 0].getAbility() != PokemonAbility.Unnerve && battlers[i].getItem() == HoldItem.Dark_Chocolate) {
                                        map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + "'s item negated the effectiveness."));
                                        basedamage *= 2;
                                        battlers[i].setItem(0);
                                    } else if (battlers[i].getAbility() == PokemonAbility.TintedLens) {
                                        map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + "'s ability negated the effectiveness."));
                                        basedamage *= 2;
                                    } else {
                                        map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + "'s attack wasn't very effective."));
                                    }
                                } else if (ee > 1.0) {
                                    if (battlers[i].getAbility() != PokemonAbility.Klutz && battlers[i].getAbility() != PokemonAbility.Unnerve && battlers[i == 1 ? 0 : 1].getItem() == HoldItem.White_Chocolate) {
                                        map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + "'s effectiveness was negated!"));
                                        basedamage /= 2;
                                        battlers[i == 1 ? 0 : 1].setItem(0);
                                    } else {
                                        map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + "'s attack was super effective!"));
                                    }
                                } else {
                                    if (battlers[i == 0 ? 1 : 0].getAbility() == PokemonAbility.WonderGuard) {
                                        basedamage = 0;
                                        map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + "'s attack was negated by Wonder Guard!"));
                                    }
                                }
                            }
                            if (atk == 0) { //defined as "contact"
                                if (battlers[i].getCurrentStatus() == null && battlers[i == 0 ? 1 : 0].getAbility() == PokemonAbility.EffectSpore && Randomizer.nextInt(100) < 50) {
                                    MonsterStatus stati = null;
                                    switch (Randomizer.nextInt(3)) {
                                        case 0:
                                            stati = MonsterStatus.MOB_STAT_Poison;
                                            break;
                                        case 1:
                                            stati = MonsterStatus.MOB_STAT_Web;
                                            break;
                                        case 2:
                                            stati = MonsterStatus.MOB_STAT_Blind;
                                            break;
                                    }
                                    final MonsterStatusEffect mse = new MonsterStatusEffect(stati, stati == MonsterStatus.MOB_STAT_Poison ? (int) (battlers[i].calcHP() / 16) : 1, MonsterStatus.genericSkill(stati), null, false, 0);
                                    battlers[i].setStatus(mse);
                                    map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + " was inflicted with " + StringUtil.makeEnumHumanReadable(stati.name()) + " status!"));
                                } else if (battlers[i].getCurrentStatus() == null && battlers[i == 0 ? 1 : 0].getAbility() == PokemonAbility.PoisonPoint && Randomizer.nextInt(100) < 50) {
                                    final MonsterStatus stati = MonsterStatus.MOB_STAT_Poison;
                                    final MonsterStatusEffect mse = new MonsterStatusEffect(stati, (int) (battlers[i].calcHP() / 16), MonsterStatus.genericSkill(stati), null, false, 0);
                                    battlers[i].setStatus(mse);
                                    map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + " was inflicted with " + StringUtil.makeEnumHumanReadable(stati.name()) + " status!"));
                                } else if (battlers[i].getCurrentStatus() == null && battlers[i == 0 ? 1 : 0].getAbility() == PokemonAbility.Static && Randomizer.nextInt(100) < 50) {
                                    final MonsterStatus stati = MonsterStatus.MOB_STAT_Web;
                                    final MonsterStatusEffect mse = new MonsterStatusEffect(stati, 1, MonsterStatus.genericSkill(stati), null, false, 0);
                                    battlers[i].setStatus(mse);
                                    map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + " was inflicted with " + StringUtil.makeEnumHumanReadable(stati.name()) + " status!"));
                                } else if (battlers[i == 0 ? 1 : 0].getAbility() == PokemonAbility.IronBarbs && battlers[i].getAbility() != PokemonAbility.MagicGuard) {
                                    map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + " got hurt " + (battlers[i].calcHP() / 8) + " damage from Rough Skin!"));
                                    battlers[i].damage((int) battlers[i].calcHP() / 8, map, 0, false);
                                    updateHP(i);
                                }
                            }
                            if (basedamage > 1 && battlers[i].getAbility() == PokemonAbility.SheerForce && Randomizer.nextInt(3) == 0) {
                                basedamage = (basedamage * 13 / 10);
                            }
                            if (basedamage > 1 && battlers[i == 0 ? 1 : 0].getAbility() != PokemonAbility.Klutz && battlers[i].getItem() == HoldItem.Mini_Dragon && battlers[i].getAbility() != PokemonAbility.MagicGuard) {
                                basedamage = (basedamage * 13 / 10);
                                battlers[i].damage((int) battlers[i].calcHP() / 8, map, battlers[i == 0 ? 1 : 0] == null ? 0 : battlers[i == 0 ? 1 : 0].getMonsterId(), true);
                                updateHP(i);
                                map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + " was hurt " + (battlers[i].calcHP() / 8) + " damage from its item!"));
                            }
                            if (battlers[i == 1 ? 0 : 1].getAbility() != PokemonAbility.BattleArmor && basedamage > 1 && critical) {
                                map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + "'s attack was a critical hit!"));
                                basedamage *= (battlers[i].getAbility() == PokemonAbility.Sniper ? 3 : 2);
                                if (battlers[i == 1 ? 0 : 1].getAbility() == PokemonAbility.AngerPoint) {
                                    map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + "'s attack triggered the foe's Anger Point!"));
                                    battlers[i == 1 ? 0 : 1].setMod(PokemonStat.ATK, battlers[i == 1 ? 0 : 1].increaseMod(battlers[i == 1 ? 0 : 1].getMod(PokemonStat.ATK)));
                                    battlers[i == 1 ? 0 : 1].setMod(PokemonStat.SPATK, battlers[i == 1 ? 0 : 1].increaseMod(battlers[i == 1 ? 0 : 1].getMod(PokemonStat.SPATK)));
                                }
                            }
                            if (basedamage > 1 && inc != null) {
                                map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + "'s " + StringUtil.makeEnumHumanReadable(inc.name()) + " increased " + (levelInc == 1 ? "slightly" : "greatly") + "!"));
                                for (int x = 0; x < levelInc; x++) {
                                    battlers[i].setMod(inc, battlers[i].increaseMod(battlers[i].getMod(inc)));
                                }
                            }
                            if (basedamage > 1 && dec != null && battlers[i == 1 ? 0 : 1].getItem() != HoldItem.Kenta_Report) {
                                map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i == 1 ? 0 : 1].getName() + "'s " + StringUtil.makeEnumHumanReadable(dec.name()) + " decreased " + (levelDec == 1 ? "slightly" : "greatly") + "!"));
                                for (int x = 0; x < levelDec; x++) {
                                    battlers[i == 1 ? 0 : 1].setMod(dec, battlers[i == 1 ? 0 : 1].decreaseMod(battlers[i == 1 ? 0 : 1].getMod(dec)));
                                }
                                if (battlers[i == 1 ? 0 : 1].getAbility() == PokemonAbility.Defiant) {
                                    for (int x = 0; x < 2; x++) {
                                        battlers[i == 1 ? 0 : 1].setMod(PokemonStat.ATK, battlers[i == 1 ? 0 : 1].increaseMod(battlers[i].getMod(PokemonStat.ATK)));
                                        battlers[i == 1 ? 0 : 1].setMod(PokemonStat.SPATK, battlers[i == 1 ? 0 : 1].increaseMod(battlers[i].getMod(PokemonStat.SPATK)));
                                    }
                                }
                            }
                            if (basedamage > 1 && flinch) {
                                map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + " absorbed " + (basedamage / 2) + " HP!"));
                                battlers[i].damage((int) -(basedamage / 2), map, 0, false);
                                updateHP(i);
                            } else if (basedamage > 1 && battlers[i].getItem() != null && battlers[i == 0 ? 1 : 0].getAbility() != PokemonAbility.Klutz && battlers[i].getItem() == HoldItem.Strange_Slush) {
                                int percentHP = (int) Math.min(100, (basedamage * 100) / battlers[i == 0 ? 1 : 0].calcHP());
                                if (percentHP > 0 && battlers[i].calcHP() > 800) {
                                    map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + " absorbed " + (percentHP * battlers[i].calcHP() / 800) + " HP!"));
                                    battlers[i].damage((int) -(percentHP * battlers[i].calcHP() / 800), map, 0, false);
                                    updateHP(i);
                                }
                            }
                            if (extraEffects && basedamage > 1 && stat != null && battlers[i == 1 ? 0 : 1].getCurrentStatus() == null && battlers[i].getAbility() != PokemonAbility.Klutz && battlers[i == 1 ? 0 : 1].getItem() != HoldItem.Pheremone) {
                                if (battlers[i].getAbility() != PokemonAbility.Klutz && battlers[i].getAbility() != PokemonAbility.Unnerve && battlers[i == 1 ? 0 : 1].getItem() == HoldItem.Pineapple) {
                                    map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i == 1 ? 0 : 1].getName() + "'s item negated the status!"));
                                    battlers[i == 1 ? 0 : 1].setItem(0);
                                } else {
                                    battlers[i == 1 ? 0 : 1].setStatus(new MonsterStatusEffect(stat, 1, MonsterStatus.genericSkill(stat), null, false, 0));
                                    map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i == 1 ? 0 : 1].getName() + " was inflicted with " + StringUtil.makeEnumHumanReadable(stat.name()) + " status!"));
                                    if (battlers[i == 1 ? 0 : 1].getAbility() == PokemonAbility.Synchronize && battlers[i].getCurrentStatus() == null && battlers[i == 0 ? 1 : 0].getAbility() != PokemonAbility.Klutz && battlers[i].getItem() != HoldItem.Pheremone) {
                                        battlers[i].setStatus(new MonsterStatusEffect(stat, stat == MonsterStatus.MOB_STAT_Poison ? (int) (battlers[i].calcHP() / 16) : 1, MonsterStatus.genericSkill(stat), null, false, 0));
                                        map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + " was inflicted with " + StringUtil.makeEnumHumanReadable(stat.name()) + " status!"));
                                    }
                                }
                            }
                            if (basedamage != 0) {
                                if (battlers[i == 1 ? 0 : 1] == null) {
                                    return;
                                }
                                if (basedamage > 1) {
                                    final byte skillByte2 = (byte) (14 + battlers[i == 1 ? 0 : 1].getMonster().getFacingDirection());
                                    AbsoluteLifeMovement alm2 = new AbsoluteLifeMovement(0, battlers[i == 1 ? 0 : 1].getMonster().getPosition(), 0, battlers[i == 1 ? 0 : 1].getMonster().getStance());
                                    alm2.defaulted();
                                    moves.add(alm2); //"hit" face
                                    // map.broadcastMessage(MobPacket.moveMonster(true, skillByte2, 0, 0, 0, battlers[i == 1 ? 0 : 1].getMonster().getObjectId(), battlers[i == 1 ? 0 : 1].getMonster().getTruePosition(), moves));
                                }
                                if (((battlers[i == 1 ? 0 : 1].getAbility() == PokemonAbility.DrySkin || battlers[i == 1 ? 0 : 1].getAbility() == PokemonAbility.WaterAbsorb) && element == PokemonElement.Fish) || (battlers[i == 1 ? 0 : 1].getAbility() == PokemonAbility.VoltAbsorb && element == PokemonElement.Lightning) || (battlers[i == 1 ? 0 : 1].getAbility() == PokemonAbility.SapSipper && element == PokemonElement.Plant)) {
                                    int percentHP = (int) Math.min(100, (basedamage * 100) / battlers[i == 0 ? 1 : 0].calcHP());
                                    if (percentHP > 0 && battlers[i == 0 ? 1 : 0].calcHP() > 800) {
                                        map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i == 1 ? 0 : 1].getName() + " absorbed " + (percentHP * battlers[i == 1 ? 0 : 1].calcHP() / 800) + " HP!"));
                                        battlers[i == 0 ? 1 : 0].damage((int) -(percentHP * battlers[i == 1 ? 0 : 1].calcHP() / 800), map, 0, false);
                                        updateHP(i == 0 ? 1 : 0);
                                    }
                                } else {
                                    if (battlers[i == 1 ? 0 : 1].getAbility() == PokemonAbility.DrySkin && element == PokemonElement.Fire) {
                                        basedamage *= 2;
                                    } else if ((battlers[i == 1 ? 0 : 1].getAbility() == PokemonAbility.ThickFat || battlers[i == 1 ? 0 : 1].getAbility() == PokemonAbility.Heatproof) && element == PokemonElement.Fire) {
                                        basedamage /= 2;
                                    } else if (battlers[i == 1 ? 0 : 1].getAbility() == PokemonAbility.ThickFat && element == PokemonElement.Ice) {
                                        basedamage /= 2;
                                    } else if (battlers[i == 1 ? 0 : 1].getAbility() == PokemonAbility.Multiscale && battlers[i == 1 ? 0 : 1].getHPPercent() >= 100) {
                                        basedamage /= 2;
                                    } else if (battlers[i == 1 ? 0 : 1].getAbility() == PokemonAbility.WeakArmor) {
                                        battlers[i == 1 ? 0 : 1].setMod(PokemonStat.SPEED, battlers[i == 1 ? 0 : 1].increaseMod(battlers[i == 1 ? 0 : 1].getMod(PokemonStat.SPEED)));
                                        battlers[i == 1 ? 0 : 1].setMod(PokemonStat.DEF, battlers[i == 1 ? 0 : 1].decreaseMod(battlers[i == 1 ? 0 : 1].getMod(PokemonStat.DEF)));
                                    } else if (battlers[i == 1 ? 0 : 1].getAbility() == PokemonAbility.MotorDrive && element == PokemonElement.Lightning) {
                                        battlers[i == 1 ? 0 : 1].setMod(PokemonStat.SPEED, battlers[i == 1 ? 0 : 1].increaseMod(battlers[i == 1 ? 0 : 1].getMod(PokemonStat.SPEED)));
                                    }
                                    map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i == 1 ? 0 : 1].getName() + " received " + basedamage + " damage!"));
                                    battlers[i == 1 ? 0 : 1].damage((int) basedamage, map, battlers[i].getMonsterId(), false);
                                    updateHP(i == 1 ? 0 : 1);
                                }
                            }
                            if (battlers[i == 1 ? 0 : 1].getCurrentHP() <= 0) {
                                //exp distribution
                                if (battlers[i] != null && battlers[i].getAbility() == PokemonAbility.Moxie) {
                                    battlers[i].setMod(PokemonStat.ATK, battlers[i].increaseMod(battlers[i].getMod(PokemonStat.ATK)));
                                    battlers[i].setMod(PokemonStat.SPATK, battlers[i].increaseMod(battlers[i].getMod(PokemonStat.SPATK)));
                                }
                                final MapleCharacter ch = map.getCharacterById(characterIds[i]);
                                if (ch != null && instanceid >= 0) {
                                    for (Battler b : ch.getBattlers()) {
                                        if (b != null && b.getItem() == HoldItem.Maha_Charm) {
                                            battlers[i == 1 ? 0 : 1].addMonsterId(b.getMonsterId());
                                        }
                                    }
                                    for (int z : battlers[i == 1 ? 0 : 1].getDamaged()) {
                                        for (Battler b : ch.getBattlers()) {
                                            if (b != null && b.getMonsterId() == z) {
                                                final int oLevel = b.getTrueLevel();
                                                final String oName = b.getStats().getName();
                                                final int xx = battlers[i == 1 ? 0 : 1].getExp(npcTeam != null, z);
                                                b.gainExp(xx, ch);
                                                ch.dropMessage(-6, b.getName() + " gained " + xx + " EXP.");
                                                ch.changedBattler();
                                                if (b.getTrueLevel() > oLevel) {
                                                    ch.dropMessage(-6, b.getName() + " leveled up to level " + b.getTrueLevel() + "!");
                                                    if (!b.getStats().getName().equals(oName)) {
                                                        ch.getClient().announce(MaplePacketCreator.playSound("5th_Maple/prize"));
                                                        ch.dropMessage(-6, b.getName() + " evolved from a " + oName + " to a " + b.getStats().getName() + "!!!");
                                                        if (b.getMonster() != null) { //respawn it
                                                            Point pos1 = b.getMonster().getPosition();
                                                            boolean left1 = !b.getMonster().isFacingLeft();
                                                            map.killMonster(b.getMonster());
                                                            spawnMonster(pos1, left1, true, b);
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                                final MapleMonsterStats mons = battlers[i == 1 ? 0 : 1].getStats();
                                map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i == 1 ? 0 : 1].getName() + " fainted!"));
                                if (battlers[i == 1 ? 0 : 1].getAbility() == PokemonAbility.Aftermath) {
                                    battlers[i].damage((int) battlers[i].calcHP() / 4, map, 0, true);
                                    updateHP(i);
                                    map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + " was hurt " + (battlers[i].calcHP() / 4) + " damage by Aftermath!"));
                                }
                                map.killMonster(battlers[i == 1 ? 0 : 1].getMonster());
                                if (battlers[i] != null) {
                                    battlers[i].removeMonsterId(battlers[i == 1 ? 0 : 1].getMonsterId());
                                }
                                battlers[i == 1 ? 0 : 1].wipe();
                                battlers[i == 1 ? 0 : 1] = null;
                                if (instanceid >= 0 && i == 0 && npcTeam == null) {
                                    final MapleCharacter chr = map.getCharacterById(characterIds[0]);
                                    chr.dropMessage(-6, "The wild monster fainted.");
                                    chr.send(MaplePacketCreator.playSound("Romio/discovery"));
                                    dispose(chr, false);
                                    return;
                                }
                                if (instanceid >= 0 && i == 0 && npcTeam != null) {
                                    if (npcTeam.size() > 0) {
                                        turn[i] = Turn.DISABLED;
                                        turn[i == 1 ? 0 : 1] = Turn.SWITCH;
                                        attacks = new String[2];
                                        switches = new Battler[2];
                                        switches[i == 1 ? 0 : 1] = new Battler(MapleLifeFactory.getMonsterStats(npcTeam.get(0)));
                                        npcTeam.remove(0);
                                    } else {
                                        final MapleCharacter chrr = map.getCharacterById(characterIds[i]);
                                        map.broadcastMessage(MaplePacketCreator.serverNotice(6, chrr.getName() + " won the match."));
                                        giveReward(chrr);
                                        forfeit(chrr, true);
                                    }
                                    return;
                                }
                                final MapleCharacter chrr = map.getCharacterById(characterIds[i == 0 ? 1 : 0]);
                                boolean cont = false;
                                for (Battler b : chrr.getBattlers()) {
                                    if (b != null && b.getCurrentHP() > 0) {
                                        cont = true;
                                        break;
                                    }
                                }
                                turn[i] = Turn.DISABLED;
                                turn[i == 1 ? 0 : 1] = cont ? null : Turn.DISABLED;
                                if (!cont) {
                                    playerWin(i);
                                    map.broadcastMessage(MaplePacketCreator.serverNotice(6, chrr.getName() + " lost the match."));
                                    forfeit(chrr, true);
                                }
                            } else {
                                if (battlers[i].getAbility() != PokemonAbility.Klutz && battlers[i].getAbility() != PokemonAbility.Unnerve && battlers[i == 0 ? 1 : 0].getItem() != null && battlers[i == 0 ? 1 : 0].getHPPercent() < (battlers[i == 0 ? 1 : 0].getAbility() == PokemonAbility.Gluttony ? 75 : 50)) {
                                    boolean usedItem = battlers[i == 0 ? 1 : 0].getAbility() == PokemonAbility.Unburden;
                                    switch (battlers[i == 0 ? 1 : 0].getItem()) {
                                        case Red_Candy:
                                            map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i == 1 ? 0 : 1].getName() + "'s attack increased from its item!"));
                                            battlers[i == 1 ? 0 : 1].setMod(PokemonStat.ATK, battlers[i == 1 ? 0 : 1].increaseMod(battlers[i == 1 ? 0 : 1].getMod(PokemonStat.ATK)));
                                            battlers[i == 1 ? 0 : 1].setMod(PokemonStat.SPATK, battlers[i == 1 ? 0 : 1].increaseMod(battlers[i == 1 ? 0 : 1].getMod(PokemonStat.SPATK)));
                                            battlers[i == 0 ? 1 : 0].setItem(0);
                                            break;
                                        case Blue_Candy:
                                            map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i == 1 ? 0 : 1].getName() + "'s defense increased from its item!"));
                                            battlers[i == 1 ? 0 : 1].setMod(PokemonStat.DEF, battlers[i == 1 ? 0 : 1].increaseMod(battlers[i == 1 ? 0 : 1].getMod(PokemonStat.DEF)));
                                            battlers[i == 1 ? 0 : 1].setMod(PokemonStat.SPDEF, battlers[i == 1 ? 0 : 1].increaseMod(battlers[i == 1 ? 0 : 1].getMod(PokemonStat.SPDEF)));
                                            battlers[i == 0 ? 1 : 0].setItem(0);
                                            break;
                                        case Green_Candy:
                                            map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i == 1 ? 0 : 1].getName() + "'s speed increased from its item!"));
                                            battlers[i == 1 ? 0 : 1].setMod(PokemonStat.SPEED, battlers[i == 1 ? 0 : 1].increaseMod(battlers[i == 1 ? 0 : 1].getMod(PokemonStat.SPEED)));
                                            battlers[i == 1 ? 0 : 1].setMod(PokemonStat.EVA, battlers[i == 1 ? 0 : 1].increaseMod(battlers[i == 1 ? 0 : 1].getMod(PokemonStat.EVA)));
                                            battlers[i == 1 ? 0 : 1].setMod(PokemonStat.ACC, battlers[i == 1 ? 0 : 1].increaseMod(battlers[i == 1 ? 0 : 1].getMod(PokemonStat.ACC)));
                                            battlers[i == 0 ? 1 : 0].setItem(0);
                                            break;
                                        case Strawberry:
                                            map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i == 1 ? 0 : 1].getName() + "'s HP healed from its item!"));
                                            battlers[i == 0 ? 1 : 0].damage((int) -(battlers[i].calcHP() / 10), map, 0, false);
                                            updateHP(i == 0 ? 1 : 0);
                                            battlers[i == 0 ? 1 : 0].setItem(0);
                                            break;
                                        default:
                                            usedItem = false;
                                            break;
                                    }
                                    if (usedItem) {
                                        battlers[i].setMod(PokemonStat.SPEED, battlers[i].increaseMod(battlers[i].getMod(PokemonStat.SPEED)));
                                    }
                                }
                                if (battlers[i].getAbility() == PokemonAbility.SpeedBoost) {
                                    battlers[i].setMod(PokemonStat.SPEED, battlers[i].increaseMod(battlers[i].getMod(PokemonStat.SPEED)));
                                } else if (battlers[i].getAbility() == PokemonAbility.Moody) {
                                    PokemonStat down = PokemonStat.getRandom(), up = PokemonStat.getRandom();
                                    for (int x = 0; x < 2; x++) {
                                        battlers[i].setMod(up, battlers[i].increaseMod(battlers[i].getMod(up)));
                                        battlers[i].setMod(down, battlers[i].decreaseMod(battlers[i].getMod(down)));
                                    }
                                    map.broadcastMessage(MaplePacketCreator.serverNotice(6, battlers[i].getName() + "'s Moody increased the " + StringUtil.makeEnumHumanReadable(up.name()) + " stat and decreased the " + StringUtil.makeEnumHumanReadable(down.name()) + " stat!"));
                                }
                            }
                        }, WALK_TIME);

                        break;
                }
            }, timeFirst);
            timeFirst += (WALK_TIME * 2) + (WALK_TIME / 8);
        }
    }
    if ((turn[0] == Turn.DISABLED || turn[1] == Turn.DISABLED || disposed) && turn[0] != Turn.SWITCH && turn[1] != Turn.SWITCH && npcTeam == null) {
        return;
    }
    Timer.EtcTimer.getInstance().schedule(() -> {
        if ((turn[0] == Turn.DISABLED || turn[1] == Turn.DISABLED || disposed) && turn[0] != Turn.SWITCH && (turn[1] != Turn.SWITCH || (npcTeam != null && battlers[1] == null))) {
            if (npcTeam != null && turn[1] == Turn.SWITCH) {
                makeTurn();
            }
            return;
        }
        final boolean[] truant = {false, false};
        switches = new Battler[2];
        attacks = new String[2];
        if (!disposed) {
            for (int i = 0; i < characterIds.length; i++) {
                updateHP(i);
                if (battlers[i] != null && battlers[i].getAbility() == PokemonAbility.Truant && turn[i] == Turn.ATTACK) {
                    truant[i] = true;
                }
            }
        }
        turn = new Turn[]{null, null};
        for (int i = 0; i < truant.length; i++) {
            if (truant[i]) {
                turn[i] = Turn.TRUANT;
            }
        }
        if (!disposed && instanceid >= 0 && turn[1] != BattleConstants.Turn.TRUANT) {
            turn[1] = makeRandomTurn();
        }
    }, timeFirst - (WALK_TIME / 8));
   }




























   public boolean isTrainerBattle() {
/* 1252 */     return (this.npcTeam != null);
   }

   public void playerWin(int i) {
/* 1256 */     int[] averageLevel = { 0, 0 }, numBattlers = { 0, 0 };
/* 1257 */     for (int x = 0; x < 2; x++) {
/* 1258 */       MapleCharacter pro = this.map.getCharacterById(this.characterIds[x]);
/* 1259 */       if (pro == null) {
         return;
       }
/* 1262 */       for (Battler b : pro.getBattlers()) {
/* 1263 */         if (b != null) {
/* 1264 */           averageLevel[x] = averageLevel[x] + b.getLevel();
/* 1265 */           numBattlers[x] = numBattlers[x] + 1;
         }
       }
/* 1268 */       averageLevel[x] = averageLevel[x] / numBattlers[x];
     }
/* 1270 */     MapleCharacter winner = this.map.getCharacterById(this.characterIds[i]);
/* 1271 */     MapleCharacter loser = this.map.getCharacterById(this.characterIds[(i == 0) ? 1 : 0]);
/* 1272 */     if (Math.abs(averageLevel[0] - averageLevel[1]) > 20 || numBattlers[0] != numBattlers[1]) {
/* 1273 */       winner.dropMessage(-6, "The battle did not count as a win due to the ease.");
/* 1274 */     } else if (!winner.canBattle(loser)) {
/* 1275 */       winner.dropMessage(-6, "The battle did not count as a win due to you battling the character in this month.");
     } else {
/* 1277 */       winner.hasBattled(loser);
/* 1278 */       winner.increaseTotalWins();
/* 1279 */       loser.increaseTotalLosses();
/* 1280 */       int theWins = winner.getIntNoRecord(122400) + 1, theWins2 = Math.max(0, loser.getIntNoRecord(122400) - 1);
/* 1281 */       winner.getQuestNAdd(MapleQuest.getInstance(122400)).setCustomData(String.valueOf(theWins));
/* 1282 */       loser.getQuestNAdd(MapleQuest.getInstance(122400)).setCustomData(String.valueOf(theWins2));
/* 1283 */       winner.dropMessage(-6, "You have gained a win on your record! Total Wins: " + winner.getTotalWins() + ", Current Wins: " + theWins);
/* 1284 */       loser.dropMessage(-6, "You have gained a loss on your record... Total Losses: " + loser.getTotalLosses() + ", Current Wins: " + theWins2);
     }
   }
 }


/* Location:              C:\PGX\Server.jar!\server\PokemonBattle.class
 * Java compiler version: 8 (52.0)
 * JD-Core Version:       1.1.3
 */